#ifndef __LR_STATEMACHINE_H__
#define __LR_STATEMACHINE_H__
//##############################################################################




/** Define an alias to indicate that a statemachine is running. */
#define LR_STATEMACHINE_RUNNING 1
//------------------------------------------------------------------------------




/** Define an alias to indicate that a statemachine is not running */
#define LR_STATEMACHINE_STOPPED 0
//------------------------------------------------------------------------------




/** Define an alias to indicate that a statemachien has been killed */
#define LR_STATEMACHINE_KILLED 2
//------------------------------------------------------------------------------




/** Forward declaration of the statemachine structure */
typedef struct ____LR_statemachine_struct LR_statemachine;




/** Type definition of a state 
 *
 * This defines the type of the state ID, used to identify and distinguish
 * between states.
*/
typedef unsigned int LR_statemachine_state;
//------------------------------------------------------------------------------




/** Type definition of a enter function.
 *
 * Second parameter is the previous state, third one indicates the new
 * (current) state.
*/
typedef void (*LR_statemachine_enter_function) ( LR_statemachine *,
                                                 LR_statemachine_state,
                                                 LR_statemachine_state );
//------------------------------------------------------------------------------




/** Type definition of a leave function.
 *
 * Second parameter is the old (current) state, third is the next state.
*/
typedef void (*LR_statemachine_leave_function) ( LR_statemachine *,
                                                 LR_statemachine_state,
                                                 LR_statemachine_state,
                                                 LR_statemachine_state );
//------------------------------------------------------------------------------




/** Type definition of a state function.
 *
 * Parameter is the current state, the return value should be the next
 * state.
*/
typedef LR_statemachine_state (*LR_statemachine_in_function)
                                            ( LR_statemachine *,
                                              LR_statemachine_state,
                                              LR_statemachine_state );
//------------------------------------------------------------------------------




/** Defintion of a state machine.
 *
 * The statemachine consists of the sum of states. Their IDs and functions
 * are saved into the 4 arrays this struct provides.
*/
struct ____LR_statemachine_struct
{
  // Size (maximal number of states, cannot be changed)
  unsigned int size;
  // Indicator for a free slot
  LR_statemachine_state no_state;
  // Map with the state ids, lookup table
  LR_statemachine_state * id_map;
  // Map with enter functions
  LR_statemachine_enter_function * enter_map;
  // Map with leave functions
  LR_statemachine_leave_function * leave_map;
  // Map with state functions
  LR_statemachine_in_function * in_map;
  // State of the statemachine (running or not)
  signed char running;
};
//##############################################################################




void LR_statemachine_init( LR_statemachine * m,
                           unsigned int size,
                           LR_statemachine_enter_function * enter_map,
                           LR_statemachine_leave_function * leave_map,
                           LR_statemachine_in_function * in_map,
                           LR_statemachine_state * id_map
                         );
//------------------------------------------------------------------------------





void LR_statemachine_add( LR_statemachine * m, LR_statemachine_state s,
                          LR_statemachine_enter_function e,
                          LR_statemachine_leave_function l,
                          LR_statemachine_in_function i
                        );
//------------------------------------------------------------------------------





int LR_statemachine_start( LR_statemachine * m, LR_statemachine_state start );
//------------------------------------------------------------------------------





void LR_statemachine_stop( LR_statemachine * m );
//------------------------------------------------------------------------------





void LR_statemachine_kill( LR_statemachine * m );
//------------------------------------------------------------------------------



#endif //__LR_STATEMACHINE_H__

